# -*- coding: utf-8 -*-
"""
author:码同学 极光
date:16
desc: 
sample: 
"""
import json

from django_celery_beat.models import CrontabSchedule, PeriodicTask
from dvadmin_celery.views.task import CeleryCrontabScheduleSerializer, PeriodicTasksSerializer
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from apitest.models import EnvInfo, ProjectInfo, ModuleInfo, TestApiInfo, TestApiResult, TestCase
from dvadmin.utils import string_util
from dvadmin.utils.serializers import CustomModelSerializer


class EnvInfoModelSerializer(CustomModelSerializer):
    """
    序列化器
    """

    def validate_paramsbody(self, value):
        if value is not None:
            if string_util.is_json(value)==False:
                raise ValidationError('不是json格式')
        return value

    class Meta:
        model = EnvInfo
        fields = "__all__"



class ProjectInfoSerializer(CustomModelSerializer):
    """
    序列化器
    """

    class Meta:
        model = ProjectInfo
        fields = "__all__"


class ModuleInfoSerializer(CustomModelSerializer):
    """
    序列化器
    """

    class Meta:
        model = ModuleInfo
        fields = "__all__"


class TestApiInfoSerializer(CustomModelSerializer):
    """
    序列化器
    """
    def validate(self, attr):
        headers  = attr.get('headers','')
        if headers!='':
            if string_util.is_json(headers) == False:
                raise ValidationError({'头部信息':'不是json格式'})
        jsonbody = attr.get('jsonbody', '')
        if jsonbody != '':
            if string_util.is_json(jsonbody) == False:
                raise ValidationError({'json参数': '不是json格式'})
        return attr

    def save(self, **kwargs):
        testinfo =  super().save(**kwargs)
        if testinfo.params_type == 1 and testinfo.jsonbody != '':
            testinfo.jsonbody=None
            testinfo.save() #修改数据库字段
        if testinfo.params_type == 2 and testinfo.params != '':
            testinfo.params = None
            testinfo.save()
        return testinfo

    class Meta:
        model = TestApiInfo
        fields = "__all__"


class TestApiResultSerializer(CustomModelSerializer):
    """
    序列化器
    """

    class Meta:
        model = TestApiResult
        fields = "__all__"


class TestApiInfoImportSerializer(CustomModelSerializer):

    def validate(self, attr):
        project_belong = attr.get('project_belong')
        module_belong = attr.get('module_belong')
        print(project_belong)
        print(module_belong)
        if module_belong.project_belong.id != project_belong.id:
            raise ValidationError({'模块信息错误': '所属模块不在工程里面'})
        return attr

    def save(self, **kwargs):
        name= self.initial_data['name']
        dbapi  = TestApiInfo.objects.filter(name=name).first()
        #修改
        if dbapi:
            dbapi.url = self.get_initial().get("url")
            dbapi.method = self.get_initial().get("method")
            dbapi.headers = self.get_initial().get("headers")
            dbapi.verification = self.get_initial().get("verification")
            dbapi.extract = self.get_initial().get("extract")
            dbapi.params = self.get_initial().get("params")
            dbapi.jsonbody = self.get_initial().get("jsonbody")
            project_id = self.get_initial().get("project_belong")
            if project_id is not None:
                dbapi.project_belong = ProjectInfo.objects.get(pk=project_id)
            module_id = self.get_initial().get("module_belong")
            if module_id is not None:
                dbapi.module_belong = ModuleInfo.objects.get(pk=module_id)
            dbapi.save() #id存在修改 update
        else:
           dbapi = super().save(**kwargs)
        return dbapi

    class Meta:
        model = TestApiInfo
        fields = "__all__"


class TestApiInfoExportSerializer(CustomModelSerializer):
    method_name = serializers.CharField(source='get_method_display', default="")

    class Meta:
        model = TestApiInfo
        fields = "__all__"


def CronSlpit(cron):
    cron = cron.split(" ")
    result = {
        # "second":cron[0],
        "minute": cron[0],
        "hour": cron[1],
        "day_of_week": cron[2],
        "day_of_month": cron[3],
        "month_of_year": cron[4]
    }
    return result

class TestCaseSerializer(CustomModelSerializer):

    class Meta:
        model = TestCase
        fields = "__all__"

    def create(self, validated_data):
        case_data= super().create(validated_data)
        # 追加 定时任务逻辑
        cron = self.get_initial().get('cron')
        if cron is not None:
            # body_data = request.data.copy()
            # cron = body_data.get('crontab_str')
            cron_data = CronSlpit(cron)
            # 添加crontab
            serializer = CeleryCrontabScheduleSerializer(data=cron_data)
            serializer.is_valid(raise_exception=True)
            print(cron_data)
            schedule, created = CrontabSchedule.objects.get_or_create(**cron_data)  # 手动创建crontab，避免重复创建
            # 添加任务
            body_data={}
            body_data['name'] = case_data.case_name
            body_data['crontab'] = schedule.id
            body_data['enabled'] = True
            env = self.request.data.get('env')
            #env = self.get_initial().get('env')
            body_data['kwargs'] = json.dumps({'case_id':case_data.id,'evn_id':env.get('id')})
            body_data['task'] = 'apitest.tasks.apiTask'
            task_serializer = PeriodicTasksSerializer(data=body_data,
                                         context={"crontab": serializer.data.get('id')})

            task_serializer.is_valid(raise_exception=True)
            task_serializer.save()
            case_data.task_id = task_serializer.data.get("id")
            case_data.save()
        return case_data


    def update(self, instance, validated_data):
        db_corn = instance.cron
        toupdate_corn = self.get_initial().get("cron")
        case_data = super().update(instance, validated_data)
        if toupdate_corn=='':
            toupdate_corn=None
        case_name = self.get_initial().get("case_name")

        #新增corn
        if toupdate_corn is not None and instance.task_id is None:
            cron_data = CronSlpit(toupdate_corn)
            # 添加crontab
            serializer = CeleryCrontabScheduleSerializer(data=cron_data)
            serializer.is_valid(raise_exception=True)
            print(cron_data)
            schedule, created = CrontabSchedule.objects.get_or_create(**cron_data)  # 手动创建crontab，避免重复创建
            # 添加任务
            body_data = {}
            body_data['name'] = case_name
            body_data['crontab'] = schedule.id
            body_data['enabled'] = True
            env = self.request.data.get('env')
            # env = self.get_initial().get('env')
            body_data['kwargs'] = json.dumps({'case_id': instance.id, 'evn_id': env.get('id')})
            body_data['task'] = 'apitest.tasks.apiTask'
            task_serializer = PeriodicTasksSerializer(data=body_data,
                                                      context={"crontab": serializer.data.get('id')})

            task_serializer.is_valid(raise_exception=True)
            task_serializer.save()
            case_data.task_id = task_serializer.data.get("id")
            case_data.save()
        # 修改corn
        if case_data.task_id is not None and toupdate_corn is not None and toupdate_corn!=db_corn:
            try:
               task=PeriodicTask.objects.get(id=case_data.task_id)
               cron_data = CronSlpit(toupdate_corn)
               schedule, created = CrontabSchedule.objects.get_or_create(**cron_data)  # 手动创建crontab，避免重复创建
               task.crontab = schedule
               task.save()
            except Exception as e:
                #删除
                case_data.task_id=None
                case_data.cron = None
                case_data.save()
        #删除
        if case_data.task_id is not None and toupdate_corn is None:
            try:
                task = PeriodicTask.objects.get(id=case_data.task_id)
                task.delete()
            except Exception as e:
                print(e)
            case_data.task_id = None
            case_data.cron = None
            case_data.save()

        return case_data



